# author:高金磊
# datetime:2022/9/9 10:46
import datetime
import time
import os
import sys
from selenium.webdriver.common.keys import Keys

from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.common.action_chains import ActionChains
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from Tools.myPrint import *

import yaml

from Tools import SendEmail
def_driver="edge"
headless=True
reset_interval=100
driver=None
optiongoogle = webdriver.ChromeOptions()
optionedge=webdriver.EdgeOptions()
option=None
count=1
def init():
    global driver,count,reset_interval,headless,option
    if def_driver == "edge":
        option=optionedge
    elif def_driver == "google":
        option=optiongoogle
    if headless:
        option.add_argument("headless")
        myPrint_Wran("后台运行浏览器，可能因为js失效导致无法使用")
    else:
        myPrint_Hint("前台运行浏览器")
def vist_url(path):
    global driver,count,reset_interval,option
    count=count%reset_interval
    if count==0:
        reset_drive(option)
    count+=1
    try:
        if driver is None:
            if def_driver == 'google':
                s = Service(ChromeDriverManager().install())
                driver = webdriver.Chrome(service=s, options=option)
            else:
                s = Service(EdgeChromiumDriverManager().install())
                driver = webdriver.Edge(service=s, options=option)
        driver.get(path)
        time.sleep(3)
        # 创建ActionChains对象并将其与WebDriver关联起来
        actions = ActionChains(driver)
        element = driver.find_element(By.XPATH, "/html/body")
        actions.move_to_element(element).perform()
        for i in range(5):  
            actions.send_keys(Keys.ARROW_DOWN * 5).perform()
            try:
                showelenium=driver.find_element(By.XPATH, "/html/body/div[1]/div/div[2]/div[3]/div[2]/span")
                if showelenium is not None and showelenium.is_displayed() and showelenium.is_enabled:
                    time.sleep(1)
                    showelenium.click()
                    break
            except Exception as e:
                myPrint_Wran("自动全文中...")
                pass
               
        # 向下滚动50像素
        for i in range(10):
            actions.move_to_element(element).perform()
            actions.send_keys(Keys.ARROW_DOWN * 3).perform()
            time.sleep(1)
        # actions.send_keys(Keys.ARROW_DOWN * 12).perform()
        myPrint_Success(path)
    except Exception as e:
        print(e)
        return str(e)
    return -1
def reset_drive(new_option=None):
    global driver,s,option
    try:
        myPrint_Hint("重置drive")
        try:
            driver.close()
        except Exception as e:
            myPrint_Hint(e)
        if new_option is not None:
            option=new_option
        driver=None
        s=None
        init()
    except Exception as e:
        myPrint_Err("重置失败，将在下次重试")

class Task:
    def __init__(self, url, describe="", start_h=-1, end_h=25, max_visit=1000, interval=5, fun=vist_url):
        self.start_h=start_h
        self.end_h=end_h
        self.max_visit=max_visit
        self.interval=interval
        self.url=url
        self.describe=describe
        self.state="ready"
        self.count=0
        self.fun=fun
    def run(self):
        if self.count>self.max_visit:
            myPrint_Success("任务已经完成,等待被销毁")
            self.state="close"
            return -2
        else:
            h=datetime.datetime.now().hour
            if h<self.start_h or h>self.end_h:
                myPrint_Wran("不在运行时间")
                time.sleep(self.interval*10)
                return -3
            s_time=time.time()
            #执行任务
            self.state="running"
            if self.fun(self.url) !=-1:
                myPrint_Wran("任务失败，下个伦次重试")
                reset_drive(option)
                time.sleep(self.interval*10)
                return -4
            self.count += 1
            use_time=time.time()-s_time
            if use_time<self.interval:
                time.sleep(max(int(self.interval-use_time),1))
            myPrint_Hint(self.describe,self.count)
            return -1
    def get_state(self):
        return self.state

if __name__ == '__main__':
    drive_names={'edge','google'}
    headless_options={'T','F','True','Fasle'}
    myPrint_Hint("支持的参数1",drive_names)
    myPrint_Hint("支持的参数2",headless_options)
    if sys.argv[1] in drive_names:
        def_driver=sys.argv[1]
        myPrint_Hint("参数生效",sys.argv[1])
    else:
        myPrint_Err("无效参数：",sys.argv[1])
        exit()
    
    if sys.argv[2] in headless_options:
        if sys.argv[2] == 'T' or sys.argv[2]=='True':
            headless=True
        else:
            headless=False
        myPrint_Hint("浏览器相关参数headless生效：",sys.argv[2])
    else:
        myPrint_Err("浏览器相关参数headless错误：",sys.argv[2])
        
        exit()
    init()
    statistical={}
    while 1:
        f = open(r"Traffic_Tools\task_list.yml", 'r', encoding='utf-8')
        config = yaml.unsafe_load(f)
        Tasks_config = config["Tasks"]

        Task_groups = []
        for task_group_name in Tasks_config.keys():
            task_group=[]
            task_details=Tasks_config[task_group_name]
            max_visit_24h=int(task_details["max_visit_24h"])
            start_time=int(task_details["start_time"])
            end_time=int(task_details["end_time"])
            interval=int(task_details["interval"])
            reset_interval=int(task_details["reset_interval"])
            urls=task_details["urls"]
            for url in urls.keys():
                task_group.append(Task(url=url,describe=urls[url],start_h=start_time,end_h=end_time,max_visit=max_visit_24h,interval=interval))
            Task_groups.append(task_group)
        f.close()
        while 1:
            flag=False
            for task_group in Task_groups:
                for task in task_group:
                    if task.state=="close":
                        continue
                    mark=task.run()
                    if mark==-1 or mark == -3:
                        flag=True
                        statistical[task.describe]=statistical.get(task.describe,0)
            if flag:
                pass
            else:
                break
        message="自上次报告以来任务执行情况如下:<br>"
        for key in statistical.keys():
            message+=str(key)+"------"+str(statistical[key])+"<br>"
        statistical={}
        SendEmail.mail("访问量_优化",  message,to_nick="流量报告接收人员",my_nick="网站访问周期任务")
        myPrint_Success(message)

